19 rosbridge 原理与环境部署
rosbridge 原理与环境部署
关联:索引
要解决的问题
- ROS2 的 Topic/Service/Action 很强,但为什么浏览器/网页端不能“直接订阅 ROS2 话题”
- rosbridge 在 ROS2 与 WebSocket 之间到底“桥接”了什么,桥接边界在哪里
- rosbridge_server 启动后,Web 客户端如何用 JSON 消息完成订阅/发布/服务调用
- 为什么同样是 WebSocket,有时只能本机访问,有时能局域网访问(端口、监听地址、权限/防火墙)
章节内容(本讲核心):
- ROS2 与 rosbridge_server 工作原理(桥接对象、数据流向、边界与风险)
- rosbridge 安装与启动(以 Ubuntu + ROS2 为例,给出可迁移步骤)
- WebSocket 连接 ROS2 机制(JSON 协议:subscribe/publish/call_service/ping)
- 端口与权限基础配置(监听地址、端口占用、基础防火墙放行与最小暴露原则)
与前置知识衔接(避免重复):
- 预设学生已掌握:WebSocket 握手与事件(open/message/error/close)、ws:// 地址与端口概念、基础日志排查方法
- 本讲不重复:WebSocket 协议二进制帧细节、前端封装与重连心跳完整工程化(已在前置覆盖)
- 本讲定位:把“WebSocket”迁移到“ROS2 场景”,理解 rosbridge 的桥接机制,并完成部署与可用性验证
本讲主要部署的是 rosbridge_server(服务端)。但为了避免“服务跑起来了却不知道用什么连”的困惑,需要明确:rosbridge 并不是“装完就自动推送数据”,它是一个需要客户端发起 WebSocket 连接并按 JSON 协议交互的接口。
rosbridge client 是什么:
-
定义:任何能连
ws://<host>:<port>,并按 rosbridge JSON 协议发送ping/subscribe/publish/call_service等消息的程序,都可以叫 rosbridge client。 -
wscat/websocat:只用于验证“能连上 + 协议能响应”,不追求工程封装与页面展示。
常见工程客户端(只做认知,不在本讲展开):
-
roslibjs:Web 前端最常用的 rosbridge 客户端库(浏览器里写 JS 即可订阅/发布)。
-
roslibpy:Python 侧的 rosbridge 客户端库(做脚本验证/数据桥接常见)。
-
ROS#(ros-sharp):Unity 场景常见的 rosbridge 客户端方案。
-
让大模型生成“rosbridge 安装与启动教程”(但必须由学生按步骤真实执行并修正不匹配处)
-
让大模型根据日志做“故障定位清单”(端口占用、ROS2 环境未 source、网络不可达等)
-
ROS2 的底层通信主要基于 DDS,中间件与网络发现机制不等同于 Web 常见协议。
-
绝大多数 Web 客户端无法直接加入 ROS2 Graph,因此需要一个“协议翻译器”。
-
rosbridge = 把 ROS2 的 Topic/Service 等能力,通过 WebSocket 暴露为 JSON 协议接口。
-
Web 端只要会 WebSocket + JSON,就能“间接”与 ROS2 交互。
1. rosbridge 解决的“接口不兼容”问题
| 侧 | 原生能力 | 不方便点 |
|---|---|---|
| ROS2 节点 | 发布/订阅/服务调用(ROS2 API) | Web 端不能直接参与 ROS2 Graph |
| Web 客户端 | WebSocket/HTTP + JSON | 不理解 ROS2 消息类型与 graph 机制 |
rosbridge_server 的角色:
- 作为 ROS2 节点加入 ROS2 Graph(因此它能订阅/发布/调用服务)
- 同时作为 WebSocket 服务器对外提供连接入口
- 在两侧之间做协议与数据结构转换(ROS2 消息 ↔ JSON)
1.1 术语澄清:rosbridge_suite、rosbridge_server 的关系(避免名词混淆)
- rosbridge_suite:一组 rosbridge 相关包的集合(元包/套件),提供“把 ROS 能力通过 JSON 协议暴露出来”的完整能力拼图。
- rosbridge_server:rosbridge_suite 里的一个包,负责提供 WebSocket 服务端入口(你启动的 9090 服务通常来自它)。
在 ROS2(Humble)里常见的构成关系(概念级):
- rosbridge_server:WebSocket 服务端实现,负责接入 Web 客户端连接
- rosbridge_library:协议与核心逻辑,负责解析 JSON 并驱动 ROS2 的发布/订阅/服务调用
- rosapi:提供一些“查询 ROS 图信息”的能力(例如话题列表等),用于客户端获取元信息
本讲为什么主要讲 rosbridge_server:
- 学生最需要的是“部署并把入口跑起来”,即能启动服务、能连上、能完成一次最小协议验证(subscribe/publish)。
- rosbridge_suite 的完整细节(每个包的 API 与更多协议操作)会显著扩展内容面,本讲只保留“名词关系”用于排障与选型理解。
2. 数据流向(必须画出来)
以“订阅话题”为例:
- Web 客户端通过 WebSocket 连接到 rosbridge_server
- Web 客户端发送 JSON:
op=subscribe,指定topic与(可选)type - rosbridge_server 在 ROS2 侧创建订阅者
- ROS2 话题有新消息时,rosbridge_server 把消息打包为 JSON,通过 WebSocket 推送给 Web 客户端
以“发布话题”为例:
- Web 客户端发送 JSON:
op=publish,带topic与msg - rosbridge_server 在 ROS2 侧创建发布者(或复用)
- 把 JSON 里的
msg转换为 ROS2 消息并发布到指定话题
3. 重要边界与风险(只讲必须的)
- rosbridge 暴露的是“控制面 + 数据面”的能力:能订阅/发布/调用服务,因此不要随意暴露到公网。
- 最小暴露原则:默认仅本机访问(localhost),需要跨机器访问时再改监听地址并配合防火墙策略。
本讲以 Ubuntu + ROS2(示例:Humble)为例。若你的 ROS2 发行版不同,把命令里的 humble 替换为你的发行版名称(例如 iron/jazzy)。
1. 前置检查:ROS2 是否已就绪
ros2 --version
- 作用:确认
ros2CLI 可用,避免后续“命令不存在/环境未安装”的误判。 - 预期:输出版本信息;若提示找不到命令,先完成 ROS2 安装或 source 环境。
如果你每次新开终端都无法使用 ros2,先执行(按你的发行版替换路径):
source /opt/ros/humble/setup.bash
- 作用:把 ROS2 的环境变量(PATH、AMENT 前缀等)注入当前终端。
- 预期:执行后
ros2 topic list等命令可正常运行。
2. 安装 rosbridge_server(apt 安装方式)
sudo apt update
sudo apt install ros-humble-rosbridge-server
- 第一行:更新本机软件索引,减少“找不到包/版本冲突”的概率。
- 第二行:安装 rosbridge_server 及其依赖(不同发行版包名会不同)。
- 自检:安装后应能看到 rosbridge 的可执行项或 launch 文件。
可用以下命令做快速自检(任选其一):
ros2 pkg list | grep rosbridge
- 作用:在已安装包列表中搜索 rosbridge 相关包。
- 预期:能看到
rosbridge_server等条目。
或:
ros2 pkg executables rosbridge_server
- 作用:列出 rosbridge_server 包内可执行程序,确认安装成功且路径可解析。
3. 启动 rosbridge WebSocket 服务(最小可用)
ros2 launch rosbridge_server rosbridge_websocket_launch.xml
- 作用:启动 rosbridge 的 WebSocket 入口(常用默认端口为 9090)。
- 预期:终端持续输出日志,且不立即退出;出现类似 “Listening on port 9090” 的信息(不同版本日志文字可能略有差异)。
- 关键点:该命令会占用当前终端,保持运行用于后续连接验证。
- 终端日志持续运行,无反复崩溃重启。
四、练习(至少 2 题)
- 用自己的话解释:为什么“学会 WebSocket”不等于“能直接连 ROS2”,rosbridge 在中间补了哪一层?
- 你认为 rosbridge 暴露到局域网有哪些风险?写出至少 2 条“最小化风险”的做法。
六、学生任务(提交物与标准)
- 提交物:运行截图(含命令与日志)、连接地址与端口、终端输出的关键日志片段(复制粘贴也可)
- 标准:信息完整且可复现(别人按你的步骤能在同环境启动)
七、大模型任务(给 AI 的指令模板 + 校验点)
把下面提示词发给大模型,要求生成“可执行的安装与启动教程”,并在你本机执行后做二次修订。
提示词:
我要在 Ubuntu(ROS2 已安装)上部署 rosbridge_server,请输出一份可执行的教程,必须包含:
1) 如何确认 ROS2 环境已就绪(给出检查命令与预期输出)
2) 如何用 apt 安装 rosbridge_server(包名要用 ros-<distro>-rosbridge-server 的形式,并说明如何替换 distro)
3) 如何启动 rosbridge websocket(给出 ros2 launch 命令)
4) 如何验证端口监听与 WebSocket 连接可用(至少给出 1 种验证工具与步骤)
5) 常见错误与修复:命令找不到、包找不到、端口占用、连接被拒绝
输出格式:分步骤编号,每步都要有“命令 + 解释 + 预期现象”。
校验点(你必须人工检查):
- 教程中的发行版名称与你的 ROS2 实际发行版一致
- 教程中的端口与地址与你的 rosbridge 实际输出一致
- 每一步都有“预期现象”,而不是只给命令
- 服务是否在跑:启动命令窗口是否存活、有无报错
- 端口是否在监听:本机 9090(或你设置的端口)是否 LISTEN
- WebSocket 是否可连接:能否握手成功
- 协议是否可用:subscribe/publish(必要时 call_service)是否按预期响应
二、工程选型提示:直连 rosbridge vs 网关转发(与第 18 衔接)
方案 A(工程更常用):ROS2/数据源 → 网关(FastAPI WebSocket)→ 浏览器页面
-
适用:工业实时推送、需要统一业务协议(
type + payload)、ROS2 在虚拟机/NAT/内网隔离环境。 -
优点:浏览器永远只连网关;鉴权、限流、日志、协议校验集中在网关做;虚拟机里 ROS2 只要能出向连到网关即可。
-
与本讲关系:本讲部署 rosbridge_server 后,后续可把 rosbridge 作为“数据源插件”接入网关,而不是让浏览器直连 ROS2 侧。
-
适用:快速验证、原型展示、需要用 roslibjs 直接订阅/发布。
-
风险:端口暴露与安全边界更难控;在虚拟机 NAT 环境下,外部访问通常需要额外处理监听地址与端口转发。
对比要点(把“为什么更推荐网关模式”说清楚):
| 维度 | 方案 A:网关转发(业务协议) | 方案 B:直连 rosbridge(通用 ROS 协议) |
|---|---|---|
| 暴露能力面 | 通常只暴露少量业务动作与状态(可控) | 订阅/发布/服务调用能力强(暴露面更大) |
| 协议与耦合 | Web 只认 type + payload,ROS2 内部 topic 可调整 |
Web 代码会出现大量 topic/type,迭代时更“前端跟着 ROS 改” |
| 安全与治理 | 鉴权/限流/审计/协议校验集中在网关 | 需要在 ROS2 侧自行承担安全与治理成本 |
| 网络可达性 | 对虚拟机/NAT 友好:ROS2 只要能“出向连接网关” | 对 NAT/多网段更敏感:浏览器要能访问到 ROS2 侧端口 |
| HTTPS/WSS | 网关更容易统一做 TLS/反向代理(https 页面通常需要 wss) | ROS2 侧要做 wss 成本更高,混合内容更容易踩坑 |
- 工业业务落地优先按方案 A 组织(与第 18 保持一致),让“业务协议”和“页面交付”稳定下来。
- 延伸阅读(更完整对比):15 FastAPI WebSocket 服务端搭建与 Vue3 客户端封装 / 16 Vue3 + FastAPI 前后端联调 / 17 WebSocket 网关 + 工业实时推送
rosbridge_server 默认常见端口是 9090,但以你启动日志为准。
用以下命令检查端口监听(任选其一):
ss -ltnp | grep 9090
ss -ltnp:列出 TCP 监听端口与进程信息(需要权限时可加 sudo)。grep 9090:过滤出 9090 相关行,确认是否处于 LISTEN。- 预期:能看到类似
LISTEN ... :9090 ...的输出。
如果系统没有 ss,可用 netstat(可能需要安装 net-tools):
netstat -lntp | grep 9090
1. 准备一个 WebSocket 客户端工具(两种常见方案)
方案 A:wscat(Node.js 工具,适合前端同学)
npm i -g wscat
- 作用:全局安装 wscat。
- 预期:安装后能运行
wscat --help。
或者:
sudo apt install node-wscat -y
方案 B:websocat(系统工具,适合服务器环境)
sudo apt install websocat
- 作用:安装 websocat。
- 预期:安装后能运行
websocat --help。
2. 建立连接
以 wscat 为例:
wscat -c ws://localhost:9090
-c:指定要连接的 WebSocket URL。ws://localhost:9090:本机访问;如果你改成局域网访问,host 会变成你的机器 IP。- 预期:显示
connected或类似提示,进入可输入消息的交互模式。
3. 重要说明:ROS2 版 rosbridge 协议通常不支持 ping/pong
如果你在 wscat 中发送下面消息并看到日志报错:
{"op":"ping","id":"ping-1"}
并且 rosbridge_server 提示 Unknown operation: ping,这是“协议不支持该 op”的表现,而不是你环境一定坏了。ROS2 版 rosbridge(v2.0 协议)常见支持的 op 以 advertise/publish/subscribe/call_service 等为主。
下面用更通用、更稳定的方式做“协议最小验证”。
4. 协议最小验证(推荐):advertise + publish + ros2 topic echo
先在虚拟机另开一个终端(不要关 rosbridge),并确保已 source ROS2:
source /opt/ros/humble/setup.bash
ros2 topic echo /wscat_test std_msgs/msg/String
- 第一行:确保当前终端有 ROS2 环境。
- 第二行:监听一个测试话题,等待 rosbridge 从 Web 侧发布消息。
回到 wscat 的交互输入,依次发送两条 JSON:
- 先 advertise(声明你要向该话题发布,指定类型):
{"op":"advertise","topic":"/wscat_test","type":"std_msgs/msg/String"}
op=advertise:告诉 rosbridge “客户端要作为发布者”。topic:要发布的 ROS2 话题名。type:建议使用 ROS2 的全写形式包名/msg/类型名,减少类型解析歧义。
- 再 publish(真正发布一条消息):
{"op":"publish","topic":"/wscat_test","msg":{"data":"hello from wscat"}}
-
op=publish:发布消息。 -
msg:必须符合该消息类型的字段结构;std_msgs/msg/String的字段就是data。 -
ros2 topic echo /wscat_test ...的终端应立刻打印出data: hello from wscat。
5. 协议最小验证(可选):subscribe /rosout(无需 talker)
如果你只想快速确认“subscribe 能工作”,可以订阅系统日志话题(可能会很密集):
{"op":"subscribe","topic":"/rosout","type":"rcl_interfaces/msg/Log"}
- 预期:wscat 会收到持续的
publish推送消息(内容为日志结构体)。
如果连接失败(连接被拒绝/超时):
- 优先回到“端口监听检查”,确认服务真的在监听
- 再确认你连接的 host/port 与启动日志一致
1. 启动 ROS2 demo talker(让系统里真的有话题在发消息)
新开一个终端(不要关掉 rosbridge 的终端),并确保已 source ROS2:
source /opt/ros/humble/setup.bash
ros2 run demo_nodes_cpp talker
- 第一行:确保当前终端有 ROS2 环境。
- 第二行:启动一个 demo 发布者,默认会向
/chatter发布std_msgs/msg/String。 - 预期:终端持续输出 “Publishing: 'Hello World: N'” 之类的日志。
2. 通过 rosbridge 订阅 /chatter(在 wscat 中操作)
在 wscat 的交互输入中发送:
{"op":"subscribe","topic":"/chatter","type":"std_msgs/String"}
op=subscribe:订阅指定 topic。topic:要订阅的话题名,必须与 ROS2 实际话题一致。type:消息类型。rosbridge v2 协议历史上常用包名/消息名这种写法(例如std_msgs/String),以兼容 roslibjs 等客户端。- 注意:少数桥接实现可能也接受 ROS2 的
包名/msg/消息名写法(例如std_msgs/msg/String)。如果订阅报错或无消息,把type换成std_msgs/msg/String再试一次。 - 预期:wscat 会持续收到 JSON 消息,典型结构类似:
{"op":"publish","topic":"/chatter","msg":{"data":"Hello World: 42"}}
你要会读这条消息:
op=publish:这里表示“服务端推送了一条话题消息”(不是让你去发布)。topic=/chatter:消息来自哪个话题。msg:ROS2 消息内容被转换成了 JSON;String 消息的字段就是data。
3. 通过 rosbridge 发布一条消息(在 wscat 中操作)
在 wscat 的交互输入中发送:
{"op":"publish","topic":"/chatter","msg":{"data":"hello from rosbridge websocket"}}
- 作用:向
/chatter发布一条字符串消息。 - 预期:如果系统里有订阅者(例如你再开一个终端运行 listener),就能看到该消息。
可选:运行 listener 验证发布是否进入 ROS2:
source /opt/ros/humble/setup.bash
ros2 run demo_nodes_cpp listener
- 预期:listener 终端会显示收到的字符串,其中应包含你从 rosbridge 发布的内容。
1. 监听地址:决定“谁能连上”
localhost/127.0.0.1:仅本机可访问(推荐默认)。0.0.0.0:监听所有网卡,局域网内其他机器可能可访问(需要配合防火墙与网络环境评估)。
如果你确实需要让同学从另一台电脑连接(局域网联调),常见做法是在启动时指定监听地址与端口(参数名以你实际 launch 文件为准):
ros2 launch rosbridge_server rosbridge_websocket_launch.xml port:=9090 address:=0.0.0.0
port:=9090:明确端口,避免默认值不一致。address:=0.0.0.0:允许外部访问(仅限可信局域网,且要做防火墙放行)。- 参数自检(建议先做一次):查看该 launch 文件支持哪些参数,避免“参数名写错但你以为生效了”:
ros2 launch rosbridge_server rosbridge_websocket_launch.xml --show-args
- 预期:终端会列出可用的 launch arguments,你可以在其中确认是否叫
port/address,以及默认值是什么。
自检方式:
- 用另一台机器访问:
ws://<你的机器IP>:9090 - 若连不上,优先检查:IP 是否可达、端口是否放行、是否有 NAT/虚拟网络隔离
1.1 VMware Workstation(NAT)场景:宿主机 Windows 如何访问虚拟机里的 rosbridge
关键结论:
- 虚拟机里写的
ws://localhost:9090只对“虚拟机自己”成立;宿主机 Windows 的localhost不是虚拟机。 - NAT 模式下,宿主机通常可以直接访问虚拟机的 NAT 网段 IP(vmnet8 网段)。局域网内其他电脑一般无法直接访问(除非做端口转发或改桥接)。
步骤 A(宿主机直接连虚拟机 IP,推荐优先用这个):
- 在 Ubuntu 虚拟机里查 IP(任选其一):
ip -4 addr show
- 作用:查看虚拟机网卡的 IPv4 地址(一般在
ens33、eth0等网卡下)。 - 预期:能看到类似
inet 192.168.x.y/24的地址,这个就是宿主机要连的目标 IP。
或:
hostname -I
- 作用:快速打印本机 IP 列表。
- 确保 rosbridge 监听对外地址(否则即使知道 IP 也连不上):
ros2 launch rosbridge_server rosbridge_websocket_launch.xml port:=9090 address:=0.0.0.0
- 作用:让 rosbridge 监听所有网卡地址(包括 NAT 网卡)。
- 安全提醒:仅在“需要从宿主机/其他机器访问”时使用;不用时建议改回 localhost。
- 在 Windows 宿主机验证端口可达(PowerShell):
Test-NetConnection <虚拟机IP> -Port 9090
- 预期:
TcpTestSucceeded : True。
- 在 Windows 宿主机用 wscat 连接(如果已安装):
wscat -c ws://<虚拟机IP>:9090
- 预期:显示 connected,并可继续按发送
ping/subscribeJSON。
步骤 B(需要“用宿主机 localhost 访问”或需要给局域网同学访问时):配置 NAT 端口转发
- 在 VMware 里打开:Virtual Network Editor → 选 VMnet8(NAT)→ NAT Settings → Port Forwarding。
- 新增规则示例:
- Host port:
19090 - Type:
TCP - Virtual machine IP address:
<虚拟机IP> - Virtual machine port:
9090
- 转发成功后,宿主机可用:
wscat -c ws://localhost:19090
- 说明:这条连接走的是“宿主机端口 → NAT 转发 → 虚拟机 9090”。
2. 防火墙放行(仅在确有需要时)
如果启用 ufw 且需要外部访问,可放行 TCP 9090:
sudo ufw allow 9090/tcp
sudo ufw status
- 第一行:允许外部访问 9090/tcp。
- 第二行:查看当前规则是否生效。
- 安全提示:不要在不需要外部访问时放行端口;更不要直接暴露到公网。
七、练习(至少 2 题)
- 解释下面两条地址的差异:
ws://localhost:9090与ws://192.168.1.10:9090。什么时候必须用后者?
- 任务 1:启动服务并记录
- 记录内容:地址(host)、端口(port)、启动命令、关键日志(截图或复制)
- 任务 2:验证服务可用性
- 至少包含:连接成功 + 协议操作成功(advertise+publish 或 subscribe)
- 推荐包含:订阅 /chatter 成功并收到消息
提示词(更偏落地执行):
请为“ROS2 + rosbridge_server 环境部署与启动”写一份教程,要求:
1) 以 Ubuntu + ROS2 Humble 为例,但同时说明如何替换为其他发行版
2) 教程必须包含:安装、启动、端口检查、WebSocket 连接验证(wscat 或 websocat 二选一即可)
3) 每个步骤都要写:命令、解释、预期输出/现象、失败时如何排查
4) 给出一段“学生需要记录的信息清单”(地址、端口、日志关键字、截图点)
输出用 Markdown,结构清晰,可直接发给同学照做。
学生的“落地修订”要求:
- 按教程执行一遍,把不适用的命令改成你机器实际可用的命令
- 把最终版本中的 ws 地址、端口、日志关键字补齐
课后作业(布置)
- 完成 rosbridge 环境部署并成功启动。
- 截图运行日志与服务状态。
- 撰写部署步骤说明(要求包含:环境信息、启动命令、ws 地址与端口、验证步骤与结果)。
参考与延伸
- rosbridge_suite(GitHub):https://github.com/RobotWebTools/rosbridge_suite
- ROS2 官方文档(选择你的发行版):https://docs.ros.org/
- 附件:Web 与 ROS2 通信方式对比(本课程内部选型说明):15 FastAPI WebSocket 服务端搭建与 Vue3 客户端封装 / 16 Vue3 + FastAPI 前后端联调 / 17 WebSocket 网关 + 工业实时推送